package cas;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * CAS操作测试代码
 * 演示CAS的基本原理和使用方式
 */
public class CASTest {
    
    // 普通的int变量，非线程安全
    private static int normalCounter = 0;
    
    // 原子整型，线程安全
    private static AtomicInteger atomicCounter = new AtomicInteger(0);
    
    // 原子引用类型
    private static AtomicReference<String> atomicReference = new AtomicReference<>("initial");
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== CAS基本操作演示 ===");
        basicCASOperation();
        
        System.out.println("\n=== 多线程环境下CAS与普通变量对比 ===");
        multiThreadComparison();
        
        System.out.println("\n=== AtomicReference CAS操作演示 ===");
        atomicReferenceDemo();
    }
    
    /**
     * 基本CAS操作演示
     */
    private static void basicCASOperation() {
        AtomicInteger atomicInt = new AtomicInteger(5);
        
        System.out.println("初始值: " + atomicInt.get());
        
        // CAS操作：期望值为5，更新为10
        boolean result1 = atomicInt.compareAndSet(5, 10);
        System.out.println("CAS(5->10): " + result1 + ", 当前值: " + atomicInt.get());
        
        // CAS操作：期望值为5（实际是10），更新为15，应该失败
        boolean result2 = atomicInt.compareAndSet(5, 15);
        System.out.println("CAS(5->15): " + result2 + ", 当前值: " + atomicInt.get());
        
        // CAS操作：期望值为10，更新为15，应该成功
        boolean result3 = atomicInt.compareAndSet(10, 15);
        System.out.println("CAS(10->15): " + result3 + ", 当前值: " + atomicInt.get());
    }
    
    /**
     * 多线程环境下CAS与普通变量的对比
     */
    private static void multiThreadComparison() throws InterruptedException {
        int threadCount = 10;
        int incrementsPerThread = 1000;
        
        // 重置计数器
        normalCounter = 0;
        atomicCounter.set(0);
        
        // 创建线程列表
        List<Thread> normalThreads = new ArrayList<>();
        List<Thread> atomicThreads = new ArrayList<>();
        
        // 创建普通变量操作线程
        for (int i = 0; i < threadCount; i++) {
            Thread thread = new Thread(() -> {
                for (int j = 0; j < incrementsPerThread; j++) {
                    normalCounter++; // 非线程安全的操作
                }
            });
            normalThreads.add(thread);
        }
        
        // 创建原子变量操作线程
        for (int i = 0; i < threadCount; i++) {
            Thread thread = new Thread(() -> {
                for (int j = 0; j < incrementsPerThread; j++) {
                    atomicCounter.incrementAndGet(); // 使用CAS实现的线程安全操作
                }
            });
            atomicThreads.add(thread);
        }
        
        // 启动所有线程
        for (Thread thread : normalThreads) {
            thread.start();
        }
        for (Thread thread : atomicThreads) {
            thread.start();
        }
        
        // 等待所有线程执行完成
        for (Thread thread : normalThreads) {
            thread.join();
        }
        for (Thread thread : atomicThreads) {
            thread.join();
        }
        
        System.out.println("普通变量结果（期望值: " + (threadCount * incrementsPerThread) + "）: " + normalCounter);
        System.out.println("原子变量结果（期望值: " + (threadCount * incrementsPerThread) + "）: " + atomicCounter.get());
    }
    
    /**
     * AtomicReference CAS操作演示
     */
    private static void atomicReferenceDemo() {
        System.out.println("初始值: " + atomicReference.get());
        
        // CAS操作：期望值为"initial"，更新为"updated"
        boolean result1 = atomicReference.compareAndSet("initial", "updated");
        System.out.println("CAS('initial'->'updated'): " + result1 + ", 当前值: " + atomicReference.get());
        
        // CAS操作：期望值为"initial"（实际是"updated"），更新为"final"，应该失败
        boolean result2 = atomicReference.compareAndSet("initial", "final");
        System.out.println("CAS('initial'->'final'): " + result2 + ", 当前值: " + atomicReference.get());
        
        // CAS操作：期望值为"updated"，更新为"final"，应该成功
        boolean result3 = atomicReference.compareAndSet("updated", "final");
        System.out.println("CAS('updated'->'final'): " + result3 + ", 当前值: " + atomicReference.get());
    }
}
